/**
 *
 * @param func 要执行的函数
 * @param delay 两次触发事件的间隔事件
 * @param options ctx 绑定的上下文
 * @returns exec 绑定【目标执行的函数】后的【实际执行函数】
 */
export const useDebounce = (func, delay, options) => {
  let flag = false;
  let ctx = options.ctx; // 绑定的上下文this
  if (!ctx) {
    throw Error("please inject the context");
  }
  const exec = () => {
    if (flag) {
      console.info("请稍后再试");
      return;
    }
    flag = true;
    func.call(ctx);
    setTimeout(() => {
      flag = false;
    }, delay);
  };
  return {
    exec,
  };
};

/**
 *
 * @param delay 两次触发事件的间隔事件
 * @param options ctx 绑定的上下文
 * @returns exec 执行函数装饰器
 */
export const useDebounce2 = (delay, options) => {
  let flag = false;
  let ctx = options.ctx; // 绑定的上下文this
  if (!ctx) {
    throw Error("please inject the context");
  }
  let _ = this;
  const exec = (func) => {
    if (flag) {
      return;
    }
    flag = true;
    func.call(_, ctx);
    setTimeout(() => {
      flag = false;
    }, delay);
  };
  return {
    exec,
  };
};

/**
 *
 * @param func 要执行的函数
 * @param options ctx 绑定的上下文
 * @returns execAsync 绑定【目标执行的函数】后的【实际执行函数】
 */
export const useDebounceAsync = (func, options) => {
  let flag = false;
  let ctx = options.ctx;
  if (!ctx) {
    throw Error("please inject the context");
  }
  const execAsync = async () => {
    if (flag) {
      console.log("您操作过快，请稍后再试");
      return;
    }
    flag = true;
    console.log("发送请求中");
    const promises = [
      new Promise(async (resolve) => {
        resolve(await func.call(ctx));
      }),
      new Promise((resolve) => {
        setTimeout(() => {
          resolve(true);
        }, 1500);
      }),
    ];
    Promise.allSettled(promises).then(() => (flag = false));
  };
  return {
    execAsync,
  };
};
